Note you will have needed to run the download.sh script to get the data.
import os
import pathlib
import plotly.express as px
# set plotly express to white theme
px.defaults.template = "plotly_white"
from dotenv import load_dotenv
from sqlalchemy import create_engine
import matplotlib.pyplot as plt
%matplotlib inline
load_dotenv("../.env")
USE_POSTGRES = os.environ.get('DATABASE_USERNAME', False)
# USE_POSTGRES = False
root_data_dir = pathlib.Path("..").resolve() / "data"
ext_data_dir = root_data_dir / "external"
geopackage = root_data_dir / "aped.gpkg"
if USE_POSTGRES:
engine = create_engine(
f"postgresql+psycopg://{os.environ.get('DATABASE_USERNAME')}:{os.environ.get('DATABASE_PASSWORD')}@localhost:5432/{os.environ.get('DATABASE_NAME')}")
else:
import sqlite3
engine = sqlite3.connect(geopackage)
G10_colors = px.colors.qualitative.G10
PARTY_COLOUR_MAP = {"Australian Greens": G10_colors[7], "Australian Labor Party": G10_colors[8],
"Coalition": G10_colors[9], "Independent": G10_colors[4]}
import pandas as pd
members = pd.read_sql("SELECT * from member_aph_46", engine)
members
| id | member_id | member | party | party_abbrev | district | is_senator | is_representative | mp_id | start | ... | RepresentedMinistries | RepresentedShadowMinistries | ParliamentaryPositions | Honours | Occupations | SecondaryOccupations | Qualifications | ElectorateService | PartyParliamentaryService | PartyCommitteeService | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 128 | Eric Abetz | Coalition | LNP | Tasmania | True | False | N26 | 1994-02-22 | ... | [Parliamentary Secretary, Special Minister of ... | [Shadow Minister, Shadow Minister, Shadow Mini... | [] | {} | [Barrister and solicitor] | [Barrister, Legal, Social and Welfare Professi... | [Bachelor of Arts, University of Tasmania, Bac... | [] | [{'RoSId': 26985, 'RoSType': 'Parliamentary Se... | [{'RoSId': 943, 'RoSType': 'Committee Service'... |
| 1 | 2 | 54 | Anthony Albanese | Australian Labor Party | ALP | Grayndler | False | True | R36 | 1996-03-02 | ... | [Cabinet Minister, Cabinet Minister, Cabinet M... | [Shadow Parliamentary Secretary, Shadow Parlia... | [] | {} | [Senior Policy Adviser to the Premier, the Hon... | [Credit or Loans Officer, Numerical Clerks, Cl... | [Bachelor of Economics, University of Sydney] | [{'Electorate': 'Grayndler', 'State': 'New Sou... | [{'RoSId': 27149, 'RoSType': 'Parliamentary Se... | [{'RoSId': 1127, 'RoSType': 'Committee Service... |
| 2 | 3 | 187 | John Alexander | Coalition | LNP | Bennelong | False | True | M3M | 2010-08-21 | ... | [] | [] | [] | {"Australian Sports Medal, 2000","Awarded a Me... | [Federation Cup Captain/Coach, 2005., Sports c... | [Tennis Coach, Sportspersons nec, Chief Execut... | [] | [{'Electorate': 'Bennelong', 'State': 'New Sou... | [{'RoSId': 27156, 'RoSType': 'Parliamentary Se... | [{'RoSId': 1133, 'RoSType': 'Committee Service... |
| 3 | 4 | 52 | Katie Allen | Coalition | LNP | Higgins | False | True | 282986 | 2019-05-18 | ... | [] | [] | [] | {"Fellow of the Australian Academy of Health a... | [Scientific Advisory Board Member at Before Br... | [Life Scientists nec, Research and Development... | [Doctor of Philosophy, University of Melbourne... | [{'Electorate': 'Higgins', 'State': 'Victoria'... | [{'RoSId': 54212, 'RoSType': 'Parliamentary Se... | [{'RoSId': 54504, 'RoSType': 'Committee Servic... |
| 4 | 5 | 235 | Anne Aly | Australian Labor Party | ALP | Cowan | False | True | 13050 | 2016-07-02 | ... | [Minister, Minister] | [] | [] | {"Australian Security Medal, 2016","Member, WA... | [Professorial Fellow, 2015., Associate Profess... | [Human Resource Manager, University Lecturer, ... | [Doctor of Philosophy, Edith Cowan University,... | [{'Electorate': 'Cowan', 'State': 'Western Aus... | [{'RoSId': 27146, 'RoSType': 'Parliamentary Se... | [{'RoSId': 1122, 'RoSType': 'Committee Service... |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 231 | 232 | 205 | Jason Wood | Coalition | LNP | La Trobe | False | True | E0F | 2013-09-07 | ... | [Assistant Minister] | [Shadow Parliamentary Secretary, Shadow Parlia... | [] | {"Awarded a Centenary Medal, 01.01.2001","Quee... | [Senior Sergeant in the Counter Terrorism Coor... | [Police Officer, Detective, Protective Service... | [Graduate Diploma Innovation Service Managemen... | [{'Electorate': 'La Trobe', 'State': 'Victoria... | [{'RoSId': 27705, 'RoSType': 'Parliamentary Se... | [{'RoSId': 2472, 'RoSType': 'Committee Service... |
| 232 | 233 | 265 | Ken Wyatt | Coalition | LNP | Hasluck | False | True | M3A | 2010-08-21 | ... | [Assistant Minister, Assistant Minister, Assis... | [] | [] | {"Indigenous Education Warrior Award, World In... | [Director for Aboriginal Health at the Departm... | [Management Consultant, Policy and Planning Ma... | [Bachelor of Education, Churchlands College of... | [{'Electorate': 'Hasluck', 'State': 'Western A... | [{'RoSId': 27710, 'RoSType': 'Parliamentary Se... | [{'RoSId': 2479, 'RoSType': 'Committee Service... |
| 233 | 234 | 242 | Terry Young | Coalition | LNP | Longman | False | True | 201906 | 2019-05-18 | ... | [] | [] | [Member of the Speaker's Panel] | {} | [Franchisee, Drummond Golf, Maroochydore from ... | [Other Factory Process Workers nfd, Service St... | [] | [{'Electorate': 'Longman', 'State': 'Queenslan... | [{'RoSId': 54008, 'RoSType': 'Parliamentary Se... | [{'RoSId': 54534, 'RoSType': 'Committee Servic... |
| 234 | 235 | 230 | Tony Zappia | Australian Labor Party | ALP | Makin | False | True | HWB | 2007-11-24 | ... | [] | [Shadow Parliamentary Secretary, Shadow Parlia... | [] | {} | [Fitness centre manager from 1981 to 2007., Re... | [Bank Worker, Fitness Centre Manager, Numerica... | [] | [{'Electorate': 'Makin', 'State': 'South Austr... | [{'RoSId': 27719, 'RoSType': 'Parliamentary Se... | [{'RoSId': 2501, 'RoSType': 'Committee Service... |
| 235 | 236 | 63 | Trent Zimmerman | Coalition | LNP | North Sydney | False | True | 203092 | 2015-12-05 | ... | [] | [] | [Member of the Speaker's Panel] | {} | [Deputy Chief Executive Officer and Director o... | [Information and Organisation Professionals ne... | [] | [{'Electorate': 'North Sydney', 'State': 'New ... | [{'RoSId': 27723, 'RoSType': 'Parliamentary Se... | [{'RoSId': 2508, 'RoSType': 'Committee Service... |
236 rows × 62 columns
Sanity checking the data Demographic details
party_counts = members.groupby(["party", "Gender"]).size().reset_index(name='count')
party_counts["%"] = (party_counts["count"] / party_counts.groupby("party")["count"].transform("sum")) * 100
party_counts
| party | Gender | count | % | |
|---|---|---|---|---|
| 0 | Australian Greens | Female | 7 | 58.333333 |
| 1 | Australian Greens | Male | 5 | 41.666667 |
| 2 | Australian Labor Party | Female | 47 | 48.453608 |
| 3 | Australian Labor Party | Male | 50 | 51.546392 |
| 4 | Centre Alliance | Female | 1 | 50.000000 |
| 5 | Centre Alliance | Male | 1 | 50.000000 |
| 6 | Coalition | Female | 29 | 25.438596 |
| 7 | Coalition | Male | 85 | 74.561404 |
| 8 | Independent | Female | 2 | 40.000000 |
| 9 | Independent | Male | 3 | 60.000000 |
| 10 | Jacqui Lambie Network | Female | 1 | 100.000000 |
| 11 | Katter's Australian Party | Male | 1 | 100.000000 |
| 12 | Liberal Democratic Party | Female | 1 | 100.000000 |
| 13 | Pauline Hanson's One Nation | Female | 1 | 50.000000 |
| 14 | Pauline Hanson's One Nation | Male | 1 | 50.000000 |
| 15 | United Australia Party [2018] | Male | 1 | 100.000000 |
# create a cut of members by age
from datetime import date
today = date.today()
members["age"] = pd.to_datetime(members["dob"]).apply(
lambda x: today.year - x.year - ((today.month, today.day) < (x.month, x.day)))
members["age_group"] = pd.cut(members["age"], bins=[18, 21, 30, 40, 50, 60, 70, 80, 90, 159],
labels=["18-20", "21-30", "31-40", "41-50", "51-60", "61-70", "71-80", "81-90", "91+"],
ordered=False)
age_counts = members.groupby(["Gender", "chamber", "age_group"]).size().reset_index(name='count')
# create a plot of members by age_counts
import plotly.express as px
px.bar(age_counts, x="age_group", y="count", color="Gender", barmode="group", facet_col="chamber",
title="Age breakdown of Australian politicians by chamber")
# two female memebers missing 2 male members 4 male senators
chamber_counts = members.groupby(["Gender", "chamber"]).size().reset_index(name='count')
px.bar(age_counts, x="chamber", y="count", color="Gender", barmode="group", title="Gender breakdown by chamber")
# calculate members age using their date of birth grouped by party
from datetime import date
today = date.today()
members["age"] = pd.to_datetime(members["dob"]).apply(
lambda x: today.year - x.year - ((today.month, today.day) < (x.month, x.day)))
members.groupby(["party"]).agg({"age": ["mean", "std"]})
| age | ||
|---|---|---|
| mean | std | |
| party | ||
| Australian Greens | 50.583333 | 9.624385 |
| Australian Labor Party | 54.144330 | 9.137822 |
| Centre Alliance | 57.500000 | 10.606602 |
| Coalition | 53.168142 | 8.774865 |
| Independent | 56.000000 | 5.196152 |
| Jacqui Lambie Network | 52.000000 | NaN |
| Katter's Australian Party | 77.000000 | NaN |
| Liberal Democratic Party | 55.000000 | NaN |
| Pauline Hanson's One Nation | 68.000000 | 0.000000 |
| United Australia Party [2018] | 59.000000 | NaN |
import plotly.express as px
fig = px.bar(party_counts, x="party", y="%", color="Gender",
title="Gender breakdown of Australian politicians by party")
fig.add_shape( # add a horizontal "target" line for 50%
type="line", line_color="salmon", line_width=3, opacity=1, line_dash="dot",
x0=0, x1=1, xref="paper", y0=50, y1=50, yref="y"
)
fig.show()
members_education = pd.read_sql("""
SELECT * from member_secondary_school_education_46
""", engine)
members_education["al_school_sector"].value_counts()
al_school_sector Government 119 Independent 79 Catholic 59 Name: count, dtype: int64
school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
["party", "school_sector"]).size().reset_index(name='count')
school_sector_counts
| party | school_sector | count | |
|---|---|---|---|
| 0 | Australian Greens | Non-government | 4 |
| 1 | Australian Greens | Public | 7 |
| 2 | Australian Labor Party | Non-government | 41 |
| 3 | Australian Labor Party | Public | 53 |
| 4 | Centre Alliance | Non-government | 1 |
| 5 | Centre Alliance | Public | 1 |
| 6 | Coalition | Non-government | 73 |
| 7 | Coalition | Public | 41 |
| 8 | Independent | Non-government | 4 |
| 9 | Independent | Public | 1 |
| 10 | Jacqui Lambie Network | Public | 1 |
| 11 | Katter's Australian Party | Public | 1 |
| 12 | Liberal Democratic Party | Public | 1 |
| 13 | Pauline Hanson's One Nation | Non-government | 1 |
| 14 | Pauline Hanson's One Nation | Public | 2 |
| 15 | United Australia Party [2018] | Public | 1 |
# create a plot of members school sector type by party
school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
["school_sector", "party", ]).size().reset_index(name='count')
fig = px.bar(school_sector_counts, x="party", y="count", color="school_sector", barmode="group",
title="School sector breakdown of Australian politicians by party")
fig.show()
members
school_sector_counts = members_education.drop_duplicates(["member", "school_sector"]).groupby(
["party", "school_sector"]).size().reset_index(name='count')
fig = px.bar(school_sector_counts, x="school_sector", y="count", color="party",
title="School sector breakdown of Australian politicians by party",
color_discrete_map=PARTY_COLOUR_MAP,
template="plotly_white")
fig.show()
Public is Government 64.4605631350012 Catholic 19.6750931104224 Independent 15.8643437545764
46th Parliament is Government 47% Catholic 20% Independent 33%
population_school_sector = {
"Catholic": 19.7,
"Government": 64.5,
"Independent": 15.8643437545764}
pop_school_sector = pd.DataFrame.from_dict(population_school_sector, orient="index").reset_index()
pop_school_sector["group"] = "Australian Population"
pop_school_sector.columns = ["school_sector", "%", "group"]
pop_school_sector
| school_sector | % | group | |
|---|---|---|---|
| 0 | Catholic | 19.700000 | Australian Population |
| 1 | Government | 64.500000 | Australian Population |
| 2 | Independent | 15.864344 | Australian Population |
# create a plot of members as a percentage school sector
school_sector_counts = members_education.drop_duplicates(["member", "al_school_sector"]).groupby(
["al_school_sector"]).size().reset_index(name='count')
school_sector_counts.rename(columns={"al_school_sector": "school_sector"}, inplace=True)
school_sector_counts["%"] = (school_sector_counts["count"] / school_sector_counts["count"].sum()) * 100
school_sector_counts["group"] = "Australian Politicians"
fig = px.bar(pd.concat([school_sector_counts, pop_school_sector]), x="school_sector", y="%",
color="group",
barmode="group", title="School sector breakdown of Australian politicians")
fig.show()
# create a plot of members as a percentage school sector depending on if is_representative or senate
school_sector_counts = members_education.drop_duplicates(["member", "al_school_sector"]).groupby(
["chamber", "al_school_sector"]).size().reset_index(name='count')
school_sector_counts["%"] = (school_sector_counts["count"] / school_sector_counts.groupby("chamber")[
"count"].transform("sum")) * 100
fig = px.bar(school_sector_counts, x="chamber", y="%", color="al_school_sector",
title="School sector breakdown of Australian politicians by party", labels={"chamber": "Chamber"})
fig.show()
# lets extract out our acara_financial data and see which school sectors are in our data
import geopandas as gpd
load_dotenv("../.env")
if USE_POSTGRES:
gdf = gpd.read_postgis(
'SELECT m.*, "total enrolments" as total_students FROM member_secondary_school_education_46 m LEFT JOIN acara_school_profile_2022 a on m.acara_id = a."acara sml id"::int',
engine, geom_col='geom')
else:
gdf_46 = gpd.read_file(geopackage, layer="member_secondary_school_education_46")
gdf_46 = gdf_46.convert_dtypes()
asp_46 = gpd.read_file(geopackage, layer="acara_school_profile_2022")[["acara sml id", "total enrolments"]]
asp_46 = asp_46.convert_dtypes()
gdf = pd.merge(gdf_46, asp_46, left_on="acara_id", right_on="acara sml id", how="left")
gdf.rename(columns={"total enrolments": "total_students"}, inplace=True)
gdf = gdf.convert_dtypes()
# fill missing students with min 50 students
gdf["total_students"] = gdf["total_students"].fillna('50').apply(lambda x: '50' if not x else x)
gdf["total_students"] = gdf["total_students"].astype(int)
# Group by party_abbrev and school_sector and avg total government funding
gdf["australian_government_recurrent_funding_per_student"] = gdf[
"australian_government_recurrent_funding_per_student"].fillna(0).astype(int)
gdf["state__territory_government_recurring_funding_per_student"] = gdf[
"state__territory_government_recurring_funding_per_student"].fillna(0).astype(int)
gdf["other_private_sources_per_student"] = gdf["other_private_sources_per_student"].fillna(0).astype(int)
gdf["total_gross_income_per_student"] = gdf["total_gross_income_per_student"].fillna(0).astype(int)
# gdf exlpore data
gdf.explore(
popup=["name", "member", "party_abbrv", "school_sector",
"total_students"],
tooltip=["name", "member", "party_abbrv", "school_sector",
"total_students"])
grouped = gdf.groupby(["party_abbrv", "school_sector"]).agg(
{"other_private_sources_per_student": "mean", "total_gross_income_per_student": "mean"}).reset_index()
px.bar(grouped, x="party_abbrv", y="other_private_sources_per_student", color="school_sector", barmode="group")
px.bar(grouped, x="party_abbrv", y="total_gross_income_per_student", color="school_sector", barmode="group")
# Select most common secondary school from members_secondary_school APH data
most_common_schools = pd.read_sql(
"SELECT secondaryschool,count(*) as members_attending FROM members_secondary_school WHERE secondaryschool != '' and secondaryschool is not null GROUP BY secondaryschool ORDER BY count(*) desc limit 10",
engine)
most_common_schools
| secondaryschool | members_attending | |
|---|---|---|
| 0 | Scotch College | 5 |
| 1 | St Ignatius College | 4 |
| 2 | St Peter's College | 4 |
| 3 | Wesley College | 4 |
| 4 | Marist College | 3 |
| 5 | Geelong Grammar School | 3 |
| 6 | Norwood High School | 2 |
| 7 | Aquinas College | 2 |
| 8 | Christian Brothers' College | 2 |
| 9 | Scotch College Melbourne | 2 |
# select those who attended the same school get value counts of name and show members who attended the same school
school_counts = members_education["name"].value_counts()
pd.merge(members_education, school_counts[school_counts > 1].reset_index(), left_on="name", right_on="name")[
["name", "member", "party", "school_sector", "count"]].sort_values(["name", "member"])
| name | member | party | school_sector | count | |
|---|---|---|---|---|---|
| 34 | Aquinas College | Brendan O'Connor | Australian Labor Party | Non-government | 2 |
| 35 | Aquinas College | Michael Sukkar | Coalition | Non-government | 2 |
| 32 | Blackburn High School | Anne Webster | Coalition | Public | 2 |
| 33 | Blackburn High School | Stephen Irons | Coalition | Public | 2 |
| 30 | Downlands College | Gerard Rennick | Coalition | Non-government | 2 |
| 31 | Downlands College | John Mcveigh | Coalition | Non-government | 2 |
| 8 | Gawler and District College | Angie Bell | Coalition | Public | 2 |
| 7 | Gawler and District College | Simon Birmingham | Coalition | Public | 2 |
| 5 | Hobart College | Eric Abetz | Coalition | Public | 2 |
| 6 | Hobart College | Nick McKim | Australian Greens | Public | 2 |
| 4 | Hobart Matriculation College | Catryna Bilyk | Australian Labor Party | Non-government | 3 |
| 3 | Hobart Matriculation College | Eric Abetz | Coalition | Non-government | 3 |
| 2 | Hobart Matriculation College | Nick McKim | Australian Greens | Non-government | 3 |
| 28 | Ipswich Grammar School | Garth Hamilton | Coalition | Non-government | 2 |
| 29 | Ipswich Grammar School | Paul Scarr | Coalition | Non-government | 2 |
| 1 | John XXIII College | Celia Hammond | Coalition | Non-government | 2 |
| 0 | John XXIII College | Hollie Hughes | Coalition | Non-government | 2 |
| 50 | Kingston College | Bert van Manen | Coalition | Public | 2 |
| 51 | Kingston College | Kristina Keneally | Australian Labor Party | Public | 2 |
| 26 | Kurri Kurri High School | Malcolm Roberts | Pauline Hanson's One Nation | Public | 2 |
| 27 | Kurri Kurri High School | Meryl Swanson | Australian Labor Party | Public | 2 |
| 48 | Lurnea High School | Anne Stanley | Australian Labor Party | Public | 2 |
| 49 | Lurnea High School | Stirling Griff | Centre Alliance | Public | 2 |
| 24 | Marcellin College | Gregory Mirabella | Coalition | Non-government | 2 |
| 25 | Marcellin College | Luke Gosling | Australian Labor Party | Non-government | 2 |
| 39 | Marist College Canberra | Daniel Mulino | Australian Labor Party | Non-government | 2 |
| 38 | Marist College Canberra | David Smith | Australian Labor Party | Non-government | 2 |
| 46 | Mount Carmel College, Charters Towers | Andrew Laming | Coalition | Public | 2 |
| 47 | Mount Carmel College, Charters Towers | Bob Katter | Katter's Australian Party | Public | 2 |
| 36 | Mount Scopus Memorial College | Josh Burns | Australian Labor Party | Non-government | 2 |
| 37 | Mount Scopus Memorial College | Joshua Frydenberg | Coalition | Non-government | 2 |
| 44 | Notre Dame College, Sheparton | Andrew Bragg | Coalition | Non-government | 2 |
| 45 | Notre Dame College, Sheparton | Kim Carr | Australian Labor Party | Non-government | 2 |
| 22 | Peninsula Grammar | Gregory Hunt | Coalition | Non-government | 2 |
| 23 | Peninsula Grammar | Tim Wilson | Coalition | Non-government | 2 |
| 20 | Prince Alfred College | Cory Bernardi | Independent | Non-government | 2 |
| 21 | Prince Alfred College | David Fawcett | Coalition | Non-government | 2 |
| 42 | Saint Ignatius' College, Riverview | Barnaby Joyce | Coalition | Non-government | 2 |
| 43 | Saint Ignatius' College, Riverview | David Gillespie | Coalition | Non-government | 2 |
| 19 | Scotch College, Melbourne | Andrew Giles | Australian Labor Party | Non-government | 2 |
| 18 | Scotch College, Melbourne | Mark Dreyfus | Australian Labor Party | Non-government | 2 |
| 16 | St Bede's College | Andrew Wallace | Coalition | Non-government | 2 |
| 17 | St Bede's College | David Van | Coalition | Non-government | 2 |
| 13 | St Peter's College | Andrew McLachlan | Coalition | Non-government | 3 |
| 14 | St Peter's College | James Stevens | Coalition | Non-government | 3 |
| 15 | St Peter's College | Scott Ryan | Coalition | Non-government | 3 |
| 52 | Tintern Grammar | Bridget McKenzie | Coalition | Non-government | 2 |
| 53 | Tintern Grammar | John Mcveigh | Coalition | Non-government | 2 |
| 11 | Unley High School | Amanda Rishworth | Australian Labor Party | Public | 2 |
| 12 | Unley High School | Mark Butler | Australian Labor Party | Public | 2 |
| 40 | Wesley College, Victoria | Julian Hill | Australian Labor Party | Non-government | 2 |
| 41 | Wesley College, Victoria | Russell Broadbent | Coalition | Non-government | 2 |
| 9 | Xavier College | Bill Shorten | Australian Labor Party | Non-government | 2 |
| 10 | Xavier College | Dan Tehan | Coalition | Non-government | 2 |
# select members who don't have a high school in education data
pd.read_sql(
"SELECT * FROM members WHERE id not in (SELECT member_id FROM member_education JOIN education e on member_education.education_id = e.id WHERE e.is_high_school = TRUE ) AND (high_school is null or high_school != 'International' ) ",
engine)
| id | orig_id | orig_table | member | district | is_senator | is_representative | graduated | start | wiki_link | dob | mp_id | party_id | chamber | high_school | preferred_name | aph_name | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 86 | 3 | 47 | Alex Antic | South Australia | True | False | True | 2019-07-01 | http://www.wikidata.org/entity/Q63520981 | 1974-12-22 | 269375 | 42 | senate | Public | Alex Antic | Alexander Antic |
| 1 | 122 | 12 | 46 | Vince Connelly | Stirling | False | True | True | 2019-05-18 | http://www.wikidata.org/entity/Q64585316 | 1978-09-16 | 282984 | 42 | house | Non-government | Vince Connelly | Vincent Connelly |
| 2 | 90 | 106 | 47 | Karen Grogan | South Australia | True | False | True | 2021-09-21 | http://www.wikidata.org/entity/Q108617920 | 1960-01-01 | 296331 | 11 | senate | None | None | Karen Grogan |
| 3 | 243 | 21 | 46 | Nicolle Flint | Boothby | False | True | True | 2016-07-02 | http://www.wikidata.org/entity/Q25756083 | 1978-07-15 | 245550 | 42 | house | Non-government | None | Nicolle Flint |
| 4 | 75 | 151 | 47 | Michelle Ananda-Rajah | Higgins | False | True | True | 2022-05-21 | http://www.wikidata.org/entity/Q90398588 | 1972-12-10 | 290544 | 11 | house | None | None | Michelle Ananda-Rajah |
| 5 | 142 | 188 | 47 | Sam Birrell | Nicholls | False | True | True | 2022-05-21 | http://www.wikidata.org/entity/Q112131083 | 1975-01-01 | 288713 | 42 | house | None | None | Sam Birrell |
| 6 | 99 | 155 | 47 | Milton Dick | Oxley | False | True | True | 2016-07-02 | http://www.wikidata.org/entity/Q20983429 | 1972-07-21 | 53517 | 11 | house | Non-government | Milton Dick | Dugald Dick |
| 7 | 93 | 173 | 47 | Peter Khalil | Wills | False | True | True | 2016-07-02 | http://www.wikidata.org/entity/Q25756187 | 1973-03-23 | 101351 | 11 | house | Non-government | None | Peter Khalil |
| 8 | 251 | 182 | 47 | Rob Mitchell | McEwen | False | True | True | 2010-08-21 | http://www.wikidata.org/entity/Q7340383 | 1967-09-09 | M3E | 11 | house | Public | Rob Mitchell | Robert Mitchell |
| 9 | 152 | 123 | 47 | Llew O'Brien | Wide Bay | False | True | False | 2016-07-02 | http://www.wikidata.org/entity/Q25756234 | 1972-06-26 | 265991 | 42 | house | None | Llew O'Brien | Llewellyn O'Brien |
| 10 | 57 | 75 | 47 | Graham Perrett | Moreton | False | True | True | 2007-11-24 | http://www.wikidata.org/entity/Q5593142 | 1966-01-05 | HVP | 11 | house | Public | None | Graham Perrett |
| 11 | 23 | 200 | 47 | Stephen Bates | Brisbane | False | True | True | 2022-05-21 | http://www.wikidata.org/entity/Q112150148 | 1992-11-23 | 300246 | 12 | house | None | None | Stephen Bates |
| 12 | 175 | 219 | 47 | Tracey Roberts | Pearce | False | True | True | 2022-05-21 | http://www.wikidata.org/entity/Q109850050 | 1960-01-01 | 157125 | 11 | house | None | None | Tracey Roberts |
| 13 | 103 | 48 | 46 | Julian Simmonds | Ryan | False | True | True | 2019-05-18 | http://www.wikidata.org/entity/Q64226194 | 1985-08-29 | 282983 | 42 | house | Non-government | None | Julian Simmonds |
| 14 | 29 | 49 | 46 | Arthur Sinodinos | New South Wales | True | False | True | 2011-10-13 | http://www.wikidata.org/entity/Q4800293 | 1957-02-25 | BV7 | 42 | senate | Public | None | Arthur Sinodinos |
| 15 | 160 | 132 | 47 | Marielle Smith | South Australia | True | False | True | 2019-07-01 | http://www.wikidata.org/entity/Q63531157 | 1986-12-30 | 281603 | 11 | senate | Both | None | Marielle Smith |
| 16 | 207 | 98 | 47 | Jordon Steele-John | Western Australia | True | False | True | 2017-11-10 | http://www.wikidata.org/entity/Q33139188 | 1994-10-14 | 250156 | 12 | senate | Home-Schooled | None | Jordon Steele-John |
| 17 | 13 | 86 | 47 | Jana Stewart | Victoria | True | False | True | 2022-04-06 | http://www.wikidata.org/entity/Q111513180 | 1987-01-01 | 299352 | 11 | senate | None | None | Jana Stewart |
| 18 | 222 | 206 | 47 | Susan Templeman | Macquarie | False | True | True | 2016-07-02 | http://www.wikidata.org/entity/Q25753992 | 1963-07-30 | 181810 | 11 | house | Public | None | Susan Templeman |
| 19 | 67 | 94 | 47 | Jess Walsh | Victoria | True | False | True | 2019-07-01 | http://www.wikidata.org/entity/Q64711059 | 1971-05-16 | 252157 | 11 | senate | Non-government | None | Jess Walsh |
| 20 | 82 | 174 | 47 | Peter Whish-Wilson | Tasmania | True | False | True | 2012-06-20 | http://www.wikidata.org/entity/Q7177677 | 1968-02-24 | 195565 | 12 | senate | Both | None | Peter Whish-Wilson |
from pywaffle import Waffle
import matplotlib.pyplot as plt
# slightly different to SMH as they set those who did not graduate or who attended overseas to other
members_46 = pd.read_sql("SELECT * FROM member_aph_46", engine)
members_46_high_school = members_46.groupby("high_school").size().reset_index(name='count')
members_46_high_school["%"] = (members_46_high_school["count"] / members_46_high_school["count"].sum()) * 100
fig = plt.figure(
FigureClass=Waffle,
rows=10,
columns=int(members_46_high_school["count"].sum() / 10),
values=members_46_high_school["%"],
figsize=(12, 5),
labels=[f"{row[1]['high_school']} ({row[1]['count']})" for row in members_46_high_school.iterrows()],
colors=G10_colors[:members_46_high_school["high_school"].shape[0]],
legend={'loc': 'upper left', 'bbox_to_anchor': (1.1, 1)}
)